package com.enation.app.javashop.core.payment.service.impl;

import com.enation.app.javashop.core.payment.model.dos.PaymentBillDO;
import com.enation.app.javashop.core.payment.model.dos.PaymentMethodDO;
import com.enation.app.javashop.core.payment.model.dto.PayParam;
import com.enation.app.javashop.core.payment.model.enums.ClientType;
import com.enation.app.javashop.core.payment.model.enums.TradeType;
import com.enation.app.javashop.core.payment.model.vo.PayBill;
import com.enation.app.javashop.core.payment.service.PaymentBillManager;
import com.enation.app.javashop.core.payment.service.PaymentManager;
import com.enation.app.javashop.core.payment.service.PaymentPluginManager;
import com.enation.app.javashop.framework.logs.Debugger;
import com.enation.app.javashop.framework.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.List;

/**
 * 支付账单管理实现
 * @author kingapex
 * @version 1.0
 * @since 7.1.0
 * 2019-04-10
 */
@Service
public class PaymentManagerImpl implements PaymentManager {

    @Autowired
    private PaymentBillManager paymentBillManager;

    @Autowired
    private List<PaymentPluginManager> paymentPluginList;

    @Autowired
    private Debugger debugger;

    @Override
    public PaymentBillDO createPaymentBill(PayBill payBill, PaymentMethodDO paymentMethod) {
        //1. 按照单号和交易类型及支付插件查询之前有没有生成交易单
        PaymentBillDO paymentBill = paymentBillManager.getBillBySnAndTradeTypeAndPaymentPluginID(payBill.getSn(),
                payBill.getTradeType().toString(), payBill.getPluginId());

        //2. 之前没有生成过支付单，再生成，避免重复生成
        if (ObjectUtils.isEmpty(paymentBill)) {

            //使用系统时间加4位随机数生成流程号 并保存支付单
            String billSn = System.currentTimeMillis() + ""+ StringUtil.getRandStr(4);
            debugger.log("为账单生成流程号："+billSn);

            // 生成支付流水payment_bill
            paymentBill = new PaymentBillDO(payBill.getSn(), billSn, null, 0, payBill.getTradeType().name(), paymentMethod.getMethodName(), payBill.getOrderPrice(), paymentMethod.getPluginId());
        }

        // 3.保存支付参数
        this.setPayConfig(payBill, paymentBill, paymentMethod);

        //4.修改或新增paymentBill
        if (paymentBill.getBillId() != null) {

            debugger.log("找到已生成的支付账单，流程号outTradeNo：" + paymentBill.getOutTradeNo());
            this.paymentBillManager.updatePaymentBill(paymentBill);
            debugger.log("账单支付参数修改成功");

        } else {
            this.paymentBillManager.add(paymentBill);
            debugger.log("账单入库成功");
        }
        //5.将已生成或者新生成的流程号赋值给支付业务实体
        payBill.setBillSn(paymentBill.getOutTradeNo());
        return paymentBill;
    }

    private void setPayConfig(PayBill payBill, PaymentBillDO paymentBill, PaymentMethodDO paymentMethod){
        //保存支付参数
        switch ( payBill.getClientType() )  {
            case PC:
                paymentBill.setPayConfig(paymentMethod.getPcConfig());
                break;
            case WAP:
                paymentBill.setPayConfig(paymentMethod.getWapConfig());
                break;
            case NATIVE:
                paymentBill.setPayConfig(paymentMethod.getAppNativeConfig());
                break;
            case REACT:
                paymentBill.setPayConfig(paymentMethod.getAppReactConfig());
                break;
            case MINI:
                paymentBill.setPayConfig(paymentMethod.getMiniConfig());
                break;
            default:
                break;
        }
    }

    @Override
    public void payReturn(TradeType tradeType, String paymentPluginId) {
        PaymentPluginManager plugin = this.findPlugin(paymentPluginId);
        if (plugin != null) {
            plugin.onReturn(tradeType);
        }
    }

    @Override
    public String payCallback(TradeType tradeType, String paymentPluginId, ClientType clientType) {
        PaymentPluginManager plugin = this.findPlugin(paymentPluginId);
        if (plugin != null) {
            return plugin.onCallback(tradeType, clientType);
        }
        return "fail";
    }

    @Override
    public String queryResult(PayParam param) {

        PaymentPluginManager plugin = this.findPlugin(param.getPaymentPluginId());

        PaymentBillDO paymentBill = this.paymentBillManager.getBillBySnAndTradeType(param.getSn(), param.getTradeType());
        //已经支付回调，则不需要查询
        if (paymentBill.getIsPay() == 1) {
            return "success";
        }

        PayBill bill = new PayBill();
        bill.setBillSn(paymentBill.getOutTradeNo());
        bill.setClientType(ClientType.valueOf(param.getClientType()));
        bill.setTradeType(TradeType.valueOf(param.getTradeType()));

        return plugin.onQuery(bill);
    }

    @Override
    public PaymentPluginManager findPlugin(String pluginId) {
        for (PaymentPluginManager plugin : paymentPluginList) {
            if (plugin.getPluginId().equals(pluginId)) {
                return plugin;
            }
        }
        return null;
    }


}
